/*
 * Copyright (c) 2006-2008 XMind Ltd. and others.
 * 
 * This file is a part of XMind 3. XMind releases 3 and above are dual-licensed
 * under the Eclipse Public License (EPL), which is available at
 * http://www.eclipse.org/legal/epl-v10.html and the GNU Lesser General Public
 * License (LGPL), which is available at http://www.gnu.org/licenses/lgpl.html
 * See http://www.xmind.net/license.html for details.
 * 
 * Contributors: XMind Ltd. - initial API and implementation
 */
package org.karelun.gef.test;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

public class LogViewer {

    public static void main(String[] args) {
        LogViewer instance;
        if (args.length > 0) {
            instance = new LogViewer(args[0]);
        } else {
            instance = new LogViewer("runtime-cathy"); //$NON-NLS-1$
        }
        instance.run();
    }

    private String userPath;

    private String logPath;

    private Display display;

    private Shell shell;

    private StyledText text;

    public LogViewer(String workspaceName) {
        this.userPath = workspaceName;
    }
    
    public void run() {
        display = new Display();
        Display.setAppName(userPath + " - log"); //$NON-NLS-1$

        shell = new Shell(display);
        shell.setText(userPath + " - log"); //$NON-NLS-1$

        GridLayout gridLayout = new GridLayout(1, false);
        gridLayout.marginWidth = 0;
        gridLayout.marginHeight = 0;
        gridLayout.verticalSpacing = 0;
        gridLayout.horizontalSpacing = 0;
        shell.setLayout(gridLayout);
        shell.addShellListener(new ShellAdapter() {
            public void shellClosed(ShellEvent e) {
                e.doit = false;
                shell.setMinimized(true);
            }
            
            @Override
            public void shellActivated(ShellEvent e) {
                reload();
            }
        });

        text = new StyledText(shell, SWT.H_SCROLL | SWT.V_SCROLL);
        text.setEditable(false);
        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        Composite toolBar = new Composite(shell, SWT.NONE);
        toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        ((GridData)toolBar.getLayoutData()).heightHint = 48;
        GridLayout gridLayout2 = new GridLayout(3, false);
        gridLayout2.marginWidth = 5;
        gridLayout2.marginHeight = 0;
        gridLayout2.verticalSpacing = 5;
        gridLayout2.horizontalSpacing = 5;
        toolBar.setLayout(gridLayout2);

        Button closeButton = new Button(toolBar, SWT.PUSH);
        closeButton.setText("Close"); //$NON-NLS-1$
        closeButton.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                shell.dispose();
            }
        });
        closeButton
                .setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));

        Button reloadButton = new Button(toolBar, SWT.PUSH);
        reloadButton.setText("Reload"); //$NON-NLS-1$
        reloadButton.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                reload();
            }
        });
        reloadButton
                .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        Button deleteButton = new Button(toolBar, SWT.PUSH);
        deleteButton.setText("Clear"); //$NON-NLS-1$
        deleteButton.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event event) {
                deleteLog();
            }
        });
        deleteButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false,
                true));

        display.asyncExec(new Runnable() {
            public void run() {
                reload();
            }
        });

        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }

        shell.dispose();
        display.dispose();

    }

    protected String getLogPath() {
        if (logPath == null) {
            logPath = findLogPath();
        }
        return logPath;
    }

    protected String findLogPath() {
        if (getUserPath().endsWith(".log")) //$NON-NLS-1$
            return getUserPath();
        String platform = SWT.getPlatform();
        if ("win32".equals(platform)) { //$NON-NLS-1$
            if (getUserPath().startsWith("C:\\") //$NON-NLS-1$
                    || getUserPath().startsWith("D:\\") //$NON-NLS-1$
                    || getUserPath().startsWith("E:\\")) { //$NON-NLS-1$
                return getUserPath() + "\\.metadata\\.log"; //$NON-NLS-1$
            }
            return "D:\\Workspace\\" + getUserPath() + "\\.metadata\\.log"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        if (getUserPath().startsWith("/")) { //$NON-NLS-1$
            return getUserPath() + "/.metadata/.log"; //$NON-NLS-1$
        }
        return System.getProperty("user.home") + "/Workspace/" + getUserPath() //$NON-NLS-1$ //$NON-NLS-2$
                + "/.metadata/.log"; //$NON-NLS-1$
    }

    protected String getUserPath() {
        return userPath;
    }

    protected void deleteLog() {
        new File(getLogPath()).delete();
        reload();
    }

    protected void reload() {
        File file = new File(getLogPath());
        if (!file.exists()) {
            text.setText("(No log)"); //$NON-NLS-1$
            return;
        }

        InputStream is;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return;
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        int num;
        byte[] buffer = new byte[1024];
        try {
            while ((num = is.read(buffer)) > 0) {
                os.write(buffer, 0, num);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        text.setText(os.toString());
        text.setSelection(text.getText().length());
    }
}